import LoginApi from "@/common/api/login.js";

import IframeView from "@/views/modules/common/IframeView.vue";
import AppUtil from "../assets/js/AppUtil";
import { Util,TokenUtil } from '@lowcode/jpaas-base-lib'
/**
 * 设置新页面（vue文件）的路由
 * @param data
 * @param modules
 * @returns {*[]}
 */
function setNewPage(data,modules){
    let _data = Util.deepClone(data)
    let arr = [];
    let filters = (item) =>{
        if(!item){ return }
        for (let i = 0 ;i < item.length ;i++){
            let menu = item[i] ;
            if(menu.showType == 'NEW_PAGE'){
                let component = loadView(menu.component,modules);
                let router = {
                    name: menu.key,
                    path: "/" + menu.key,
                    component: component,
                    props:true,
                    meta: {
                        menuType: menu.menuType,
                        params: menu.params,
                        id: menu.id
                    }
                }
                arr.push(router);
            }
            if(menu.children){
                filters(menu.children);
            }
        }
    }
    filters(_data.children);
    return arr;
}

function setParentRouter(microAppRouter,name,menu){
    let parentRouter = microAppRouter.find(route=>route.name === name);
    if(!parentRouter){
        parentRouter = {
            name: name,
            path: name,
            children:[],
            title:menu.title,
        }
        microAppRouter.push(parentRouter)
    }
    return parentRouter
}

/**
 * 获取用户与路由菜单信息
 * @returns {Promise<any>}
 * 是否有系统菜单，能进入后台 isAdmin boolean
 */
/*buildTree中赋值*/
let isAdmin = false ;
export const generatorDynamicRouter = (mainComponent,modules) => {
    return new Promise((resolve, reject) => {
        LoginApi.getLoginUserAndMenu().then(res => {
            let allMenuButtons = res.data.allMenuButtons;
            let user = res.data.user;
            //转成树形路由
            let menus = buildMenu(res.data.menus,res.data.user);
            let allRouter = buildAllRouter(res.data.menus,res.data.user);
            let routers = [];
            let microApp = {}
            //构建空路由
            let microAppRouter = []

            for (let i = 0; i < allRouter.length; i++) {
                if(allRouter[i].parentModule === 'InnerLayout'){ continue }
                let ary = [],microRouter = [];
                let menu = allRouter[i];
                let {appPath,menuNavType} = menu ;
                let parentRouter = null,
                    appRouter = null;


                if(appPath && menuNavType === "2"){
                    //内嵌微前端配置
                    //拼接出 内嵌微前端的url ;
                    let name = appPath.replace('/','').trim()
                    let _path = `/${name}/${menu.key}`;
                    let _key = `${name}-${menu.key}`;
                    microApp[_key] = _path ;

                    parentRouter = setParentRouter(microAppRouter,name,menu);
                    appRouter = {
                        name: menu.key,
                        path: menu.key,
                        children:[],
                        meta:{ menuType: menu.menuType, title:menu.title, appId:menu.appId, menuKey:menu.key }
                    }
                    parentRouter.children = [...parentRouter.children,appRouter]
                }
                let newPage = setNewPage(menu,modules);
                menu.path = "/" + menu.key;
                buildRouters(menu, ary,modules,parentRouter? microRouter:'');
                routers = [...routers,...newPage,...ary];
                if(appRouter){
                    appRouter.children = microRouter
                }
            }
            let obj={
                menus:menus,
                allMenuButtons:allMenuButtons,
                user:user,
                routers:routers,
                haveHomePage:res.data.haveHomePage,
                microApp,
                microAppRouter,
                isAdmin
            }
            resolve(obj);
        }).catch(err => {
            reject(err);
        })
    })
}

/**
 * 构建路由
 * @param parent
 * @param routers
 */
function buildRouters(parent,routers,modules,microRouter) {
    if (!parent.children) {
        return;
    }
    for (let i = 0; i < parent.children.length; i++) {
        let menu = parent.children[i];
        let path=(parent.path || "")  + (parent.path ? "/": "") + menu.key;
        menu.path = path;
        if( (menu.menuType !== 'C' && menu.menuType !== 'R') || menu.showType === 'NEW_PAGE'){
            continue;
        }
        let component = getComponent(menu,modules);
        //判断是否需要拼接token url最后为&accessToken结尾则拼接token
        if (menu.params && typeof (menu.params) == 'string') {
            let str = menu.params.substring(menu.params.indexOf("&"));
            if (str == "&accessToken") {
                let accessToken = TokenUtil.getToken();
                if (accessToken) {
                    menu.params = menu.params + "=" + accessToken;
                }
            }
        }
        let router = {
            name: menu.key+(menu.id?'_'+menu.id:''),
            path: path,
            component: component,
            meta: {
                menuType: menu.menuType,
                params: menu.params,
                id: menu.id,
                keepAlive:true
            }
        };
        routers.push(router);
        if(microRouter){//内置微前端路由
            let obj = {
                name: menu.key,
                path: path,
                meta: {
                    menuType: menu.menuType,
                    params: menu.params,
                    id: menu.id,
                    title:menu.title,
                    appId:menu.appId,
                    menuKey:menu.key,
                    keepAlive:true
                }
            }
            microRouter.push(obj)
        }
        buildRouters(menu, routers,modules,microRouter)
    }
}

/**
 * 路由懒加载
 * @param view
 * @returns {*}
 */
export function loadView(view,modules){
    if(!view){
        return "";
    }
    let url = view.includes(".vue")?view : view+".vue";
    let component = modules[`/src/views/${url}`]
    return  component;
}

/**
 * 获取组件
 * @param menu
 * @returns {null}
 */
export function getComponent(menu,modules) {
    let component=null;
    if (!menu.settingType || menu.settingType === "iframe") {
        component = IframeView;
    }else if (menu.settingType === "custom" || menu.component) {
        if (typeof menu.component === "function") {
            component = menu.component;
        } else {
            //需要异步加载页面
            component = AppUtil.loadComponent(menu.component,modules,false);
        }
    }
    return component;
}

/**
 * 构建菜单
 * @param rows
 * @returns {*[]}
 */
function buildMenu(rows,user) {
    let newRows = [];
    rows.forEach(item => {
        if (item.menuType != "F" && item.menuType != "I"  && item.menuType != "R") {
            newRows.push(item);
        }
    });
    const menus = [];
    buildTree(newRows, menus, '0',user);
    for (let i = 0; i < menus.length; i++) {
        if (menus[i].children) {
            menus[i].children.sort(compareSn('sn'));
        }
    }
    return menus;
}


/**
 * 构建路由。
 * @param rows
 * @returns {[]}
 */
export function buildAllRouter(rows, user) {
    var newRouters = [];
    rows.forEach(item => {
        // 路由需要显示路由类型的，不排除
        if (item.menuType != "F" && item.menuType != "I" ) {
            newRouters.push(item);
        }
    });
    const routers = [];
    buildTree(newRouters, routers, '0', user);
    for (var i = 0; i < routers.length; i++) {
        if (routers[i].children) {
            routers[i].children.sort(compareSn('sn'));
        }
    }

    return routers;
}

/*
 * 将菜单构建成树状
 * @param list
 * @param arr
 * @param parentId
 */
function buildTree(list, arr, parentId,user, appType, menuNavType) {
    for (let item of list){
        /*如果是系统应用则过滤掉*/
        if(item.navType === 1){
            isAdmin = true
            continue ;
        }
        if (item.parentId === parentId) {
            if (item.instConfig) {
                let insConfig=item.instConfig.trim();
                if(insConfig.startsWith("{") ){
                    var instConfigs = JSON.parse(insConfig);
                    for (let i = 0; i < instConfigs.length; i++) {
                        if (instConfigs[i].instLabel == user.tenantLabel) {
                            item.component = instConfigs[i].component;
                            item.params = instConfigs[i].params;
                        }
                    }
                }
            }
            let child = {
                title: item.name,
                remarks: item.remarks,
                menuKey: item.menuKey,
                key: item.menuKey,
                id: item.id,
                sn: item.sn,
                icon: item.iconPc,
                showType: item.showType,
                menuType: item.menuType,
                settingType: item.settingType,
                component: item.component,
                layout: item.layout,
                parentModule: item.parentModule,
                params: item.params,
                children: [],
                appType: item.appType || appType,
                appPath: item.appPath,
                menuNavType:menuNavType || item.menuNavType ,
                backColor: item.backColor,
                isFav: item.isFav,
                lastUseTime: item.lastUseTime,
                appId: item.appId,
                categoryId: item.categoryId,
                navType:item.navType,
                haveHomePage:item.haveHomePage
            }
            buildTree(list, child.children, item.id, user, child.appType, child.menuNavType)
            if (child.children.length === 0) {
                delete child.children
            }
            arr.push(child)
        }
    }
}

/**
 * 排序
 * @param property
 * @returns {function(*, *)}
 */
function compareSn(property) {
    return function (obj, obj2) {
        return obj[property] - obj2[property]
    }
}

/**
 * 根据key找到菜单。
 * @param key
 * @param menus
 */
export function getMenuByKey(key,menus){
    let getMenu=function (key,menus){
        let menu;
        for (let i = 0; i <menus.length ; i++) {
            let item=menus[i];
            if(item.key==key){
                menu=item;
                break;
            }else {
                if(item.children&&item.children.length>0){
                    menu=getMenu(key,item.children);
                    if(menu) break;
                }
            }
        }
        return menu;
    }
    let menu=getMenu(key,menus);
    return menu;
}
